home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / dev / lang / Python16_Src.lha / Python16_Source / Python / pystate.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-09-10  |  4.7 KB  |  225 lines

  1. /* Thread and interpreter state structures and their interfaces */
  2.  
  3. #include "Python.h"
  4. #include "protos/pystate.h"
  5.  
  6. #define ZAP(x) { \
  7.     PyObject *tmp = (PyObject *)(x); \
  8.     (x) = NULL; \
  9.     Py_XDECREF(tmp); \
  10. }
  11.  
  12.  
  13. #ifdef WITH_THREAD
  14. #include "pythread.h"
  15. static PyThread_type_lock head_mutex = NULL; /* Protects interp->tstate_head */
  16. #define HEAD_INIT() (head_mutex || (head_mutex = PyThread_allocate_lock()))
  17. #define HEAD_LOCK() PyThread_acquire_lock(head_mutex, WAIT_LOCK)
  18. #define HEAD_UNLOCK() PyThread_release_lock(head_mutex)
  19. #else
  20. #define HEAD_INIT() /* Nothing */
  21. #define HEAD_LOCK() /* Nothing */
  22. #define HEAD_UNLOCK() /* Nothing */
  23. #endif
  24.  
  25. static PyInterpreterState *interp_head = NULL;
  26.  
  27. PyThreadState *_PyThreadState_Current = NULL;
  28.  
  29.  
  30. PyInterpreterState *
  31. PyInterpreterState_New()
  32. {
  33.     PyInterpreterState *interp = PyMem_NEW(PyInterpreterState, 1);
  34.  
  35.     if (interp != NULL) {
  36.         HEAD_INIT();
  37.         interp->modules = NULL;
  38.         interp->sysdict = NULL;
  39.         interp->builtins = NULL;
  40.         interp->checkinterval = 10;
  41.         interp->tstate_head = NULL;
  42.  
  43.         interp->next = interp_head;
  44.         interp_head = interp;
  45.     }
  46.  
  47.     return interp;
  48. }
  49.  
  50.  
  51. void
  52. PyInterpreterState_Clear(interp)
  53.     PyInterpreterState *interp;
  54. {
  55.     PyThreadState *p;
  56.     HEAD_LOCK();
  57.     for (p = interp->tstate_head; p != NULL; p = p->next)
  58.         PyThreadState_Clear(p);
  59.     HEAD_UNLOCK();
  60.     ZAP(interp->modules);
  61.     ZAP(interp->sysdict);
  62.     ZAP(interp->builtins);
  63. }
  64.  
  65.  
  66. static void
  67. zapthreads(interp)
  68.     PyInterpreterState *interp;
  69. {
  70.     PyThreadState *p;
  71.     /* No need to lock the mutex here because this should only happen
  72.        when the threads are all really dead (XXX famous last words). */
  73.     while ((p = interp->tstate_head) != NULL) {
  74.         PyThreadState_Delete(p);
  75.     }
  76. }
  77.  
  78.  
  79. void
  80. PyInterpreterState_Delete(interp)
  81.     PyInterpreterState *interp;
  82. {
  83.     PyInterpreterState **p;
  84.     zapthreads(interp);
  85.     for (p = &interp_head; ; p = &(*p)->next) {
  86.         if (*p == NULL)
  87.             Py_FatalError(
  88.                 "PyInterpreterState_Delete: invalid interp");
  89.         if (*p == interp)
  90.             break;
  91.     }
  92.     if (interp->tstate_head != NULL)
  93.         Py_FatalError("PyInterpreterState_Delete: remaining threads");
  94.     *p = interp->next;
  95.     PyMem_DEL(interp);
  96. }
  97.  
  98.  
  99. PyThreadState *
  100. PyThreadState_New(interp)
  101.     PyInterpreterState *interp;
  102. {
  103.     PyThreadState *tstate = PyMem_NEW(PyThreadState, 1);
  104.  
  105.     if (tstate != NULL) {
  106.         tstate->interp = interp;
  107.  
  108.         tstate->frame = NULL;
  109.         tstate->recursion_depth = 0;
  110.         tstate->ticker = 0;
  111.         tstate->tracing = 0;
  112.  
  113.         tstate->dict = NULL;
  114.  
  115.         tstate->curexc_type = NULL;
  116.         tstate->curexc_value = NULL;
  117.         tstate->curexc_traceback = NULL;
  118.  
  119.         tstate->exc_type = NULL;
  120.         tstate->exc_value = NULL;
  121.         tstate->exc_traceback = NULL;
  122.  
  123.         tstate->sys_profilefunc = NULL;
  124.         tstate->sys_tracefunc = NULL;
  125.  
  126.         HEAD_LOCK();
  127.         tstate->next = interp->tstate_head;
  128.         interp->tstate_head = tstate;
  129.         HEAD_UNLOCK();
  130.     }
  131.  
  132.     return tstate;
  133. }
  134.  
  135.  
  136. void
  137. PyThreadState_Clear(tstate)
  138.     PyThreadState *tstate;
  139. {
  140.     if (Py_VerboseFlag && tstate->frame != NULL)
  141.         fprintf(stderr,
  142.           "PyThreadState_Clear: warning: thread still has a frame\n");
  143.  
  144.     ZAP(tstate->frame);
  145.  
  146.     ZAP(tstate->dict);
  147.  
  148.     ZAP(tstate->curexc_type);
  149.     ZAP(tstate->curexc_value);
  150.     ZAP(tstate->curexc_traceback);
  151.  
  152.     ZAP(tstate->exc_type);
  153.     ZAP(tstate->exc_value);
  154.     ZAP(tstate->exc_traceback);
  155.  
  156.     ZAP(tstate->sys_profilefunc);
  157.     ZAP(tstate->sys_tracefunc);
  158. }
  159.  
  160.  
  161. void
  162. PyThreadState_Delete(tstate)
  163.     PyThreadState *tstate;
  164. {
  165.     PyInterpreterState *interp;
  166.     PyThreadState **p;
  167.     if (tstate == NULL)
  168.         Py_FatalError("PyThreadState_Delete: NULL tstate");
  169.     if (tstate == _PyThreadState_Current)
  170.         Py_FatalError("PyThreadState_Delete: tstate is still current");
  171.     interp = tstate->interp;
  172.     if (interp == NULL)
  173.         Py_FatalError("PyThreadState_Delete: NULL interp");
  174.     HEAD_LOCK();
  175.     for (p = &interp->tstate_head; ; p = &(*p)->next) {
  176.         if (*p == NULL)
  177.             Py_FatalError(
  178.                 "PyThreadState_Delete: invalid tstate");
  179.         if (*p == tstate)
  180.             break;
  181.     }
  182.     *p = tstate->next;
  183.     HEAD_UNLOCK();
  184.     PyMem_DEL(tstate);
  185. }
  186.  
  187.  
  188. PyThreadState *
  189. PyThreadState_Get()
  190. {
  191.     if (_PyThreadState_Current == NULL)
  192.         Py_FatalError("PyThreadState_Get: no current thread");
  193.  
  194.     return _PyThreadState_Current;
  195. }
  196.  
  197.  
  198. PyThreadState *
  199. PyThreadState_Swap(new)
  200.     PyThreadState *new;
  201. {
  202.     PyThreadState *old = _PyThreadState_Current;
  203.  
  204.     _PyThreadState_Current = new;
  205.  
  206.     return old;
  207. }
  208.  
  209. /* An extension mechanism to store arbitrary additional per-thread state.
  210.    PyThreadState_GetDict() returns a dictionary that can be used to hold such
  211.    state; the caller should pick a unique key and store its state there.  If
  212.    PyThreadState_GetDict() returns NULL, an exception has been raised (most
  213.    likely MemoryError) and the caller should pass on the exception. */
  214.  
  215. PyObject *
  216. PyThreadState_GetDict()
  217. {
  218.     if (_PyThreadState_Current == NULL)
  219.         Py_FatalError("PyThreadState_GetDict: no current thread");
  220.  
  221.     if (_PyThreadState_Current->dict == NULL)
  222.         _PyThreadState_Current->dict = PyDict_New();
  223.     return _PyThreadState_Current->dict;
  224. }
  225.